/*\
停车场管理系统（扩展版）
我们来扩展之前的停车场管理系统，添加一个停车场管理员的角色。
管理员的职责是监控停车场的状态，只有当停车场有空位时才允许车辆进入。
车辆进入和离开停车场都需要加锁，确保同时只有一个线程在操作停车位状态。
同时使用信号量来控制停车场的容量，使用互斥锁来保护共享数据（停车位状态）。
*/

#include <head.h>

// 定义变量
pthread_t Tid[2];
pthread_mutex_t mutex;
sem_t sem;
int num = 11;    // 待停车数量
int ing_num = 0; // 停车位数量
int arr[10] = {1, 2, 3, 4, 5, 6, 7, 8, 9, 10};

int m = 0;
// 声明线程函数
void *func(void *val);
void *func_1(void *val);
int main(int argc, char const *argv[])
{
    // 初始化互斥锁和无名变量
    pthread_mutex_init(&mutex, NULL);
    sem_init(&sem, 0, 0);

    // 创建线程
    pthread_create(&Tid[0], NULL, func, NULL); // 管理员线程
                                               // 创建车辆线程
    pthread_create(&Tid[1], NULL, func_1, NULL);

    // 工作
    printf("十辆车等待停车\n");
    // 进行V操作
    sem_post(&sem);

    // 回收线程
    pthread_join(Tid[0], NULL);

    pthread_join(Tid[1], NULL);

    // 销毁互斥锁
    pthread_mutex_destroy(&mutex);

    return 0;
}

void *func(void *val)
{
    // 开锁
    // pthread_mutex_lock(&mutex);

    while (1)
    {
        // if (ing_num<3)
        // {   printf("=================\n");
        //     printf("当前停车位剩余 %d 个\n",3-ing_num);
        // }
        if (ing_num == 3)
        {
            sleep(2);
            printf("=======小车 %d 结束停车 \n", arr[m]);
            m++;
            ing_num--;
        }
        if (m > 7)
        {
            sleep(2);
            printf("=======小车 %d 结束停车 \n", arr[m]);
            m++;
            ing_num--;
        }
        if(m==10)
        {
            break;
        }
    }

    // 解锁
    // pthread_mutex_lock(&mutex);

    return NULL;
}

void *func_1(void *val)
{
    // for (int i = 0; i < 10; i++)
    // {
    //     printf("小车 %d 等待停车 \n",*(int *)val );
    // }

    // 开锁
    pthread_mutex_lock(&mutex);
    printf("1111\n");
    for (int i = 0; i < 10; i++)

    {
        sleep(2);
        if (ing_num < 3)
        {
            sleep(1);
            sem_wait(&sem);
            printf("小车 %d 开始停车-----> \n", arr[i]);
            ing_num++;
            sleep(2);
            sem_post(&sem);
        }
    }

    // 解锁
    pthread_mutex_unlock(&mutex);

    return NULL;
}
